#include <stdio.h>
#include "head.h"

pthread_mutex_t mutex; // 定义互斥锁

int sever_main(char *addr, const char *port)
{
    // 创建互斥锁
    pthread_mutex_init(&mutex, NULL);
    // 1. 创建套接字
    int Sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (Sock_fd == -1)
    {
        ERRLOG("socket error");
        return -1;
    }

    // 2. 填充服务器网络信息结构体
    struct sockaddr_in Sock_addr;
    Sock_addr.sin_family = AF_INET;
    Sock_addr.sin_port = htons(atoi(port));
    Sock_addr.sin_addr.s_addr = inet_addr(addr);

    // 3. 绑定
    if (bind(Sock_fd, (struct sockaddr *)&Sock_addr, sizeof(Sock_addr)) == -1)
    {
        ERRLOG("bind error");
        close(Sock_fd);
        return -1;
    }

    // 4. 监听
    if (listen(Sock_fd, 10) == -1)
    {
        ERRLOG("listen error");
        close(Sock_fd);
        return -1;
    }

    while (1)
    {
        // 5. 等待客户端连接

        struct sockaddr_in client_addr;
        socklen_t addr_len = sizeof(client_addr);

        int client_socket = accept(Sock_fd, (struct sockaddr *)&client_addr, &addr_len);

        thread_data_t *data = malloc(sizeof(thread_data_t));
        if (data == NULL)
        {
            perror("内存分配失败");
            close(Sock_fd);
            continue; // 继续接受下一个连接
        }

        // 填充结构体
        data->client_socket = client_socket;
        data->client_addr = client_addr;

        pthread_t Tid;
        if (pthread_create(&Tid, NULL, Server, data) != 0)
        {
            ERRLOG("pthread_create error");
            free(data);
        }
        pthread_detach(Tid);
    }

    close(Sock_fd);
    return 0;
}

void *Server(void *arg)
{
    thread_data_t *data = (thread_data_t *)arg;

    // 获取连接者的 IP 和端口
    char ip[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &data->client_addr.sin_addr, ip, sizeof(ip));
    // int port = ntohs(data->client_addr.sin_port);
    int Sock_fd = data->client_socket;

    // 向新连接的用户发送连接成功消息
    const char *welcome_msg = "连接成功，欢迎使用聊天系统！ \n   登录(login_user_passwrod_)\n   注册(enroll_user_passwrod_) \n ";
    send(Sock_fd, welcome_msg, strlen(welcome_msg), 0);

    // 启动接收线程
    pthread_t r_tid;

    pthread_create(&r_tid, NULL, R_Server, data);

    // 启动发送线程
    W_Server((void *)&Sock_fd);

    close(Sock_fd); // 关闭套接字
    return NULL;
}

void *W_Server(void *arg)
{
    int Sock_fd = *((int *)arg);
    char buf[1024];

    while (1)
    {
        memset(buf, 0, sizeof(buf));
        printf("发送: ");
        fgets(buf, sizeof(buf), stdin);

        // 移除换行符
        buf[strcspn(buf, "\n")] = 0;

        if (send(Sock_fd, buf, strlen(buf), 0) == -1)
        {
            printf("发送失败\n");
            break;
        }
    }
    return NULL;
}

void *R_Server(void *arg)
{
    thread_data_t *data = (thread_data_t *)arg;

    // 获取连接者的 IP 和端口
    char ip[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &data->client_addr.sin_addr, ip, sizeof(ip));
    int port = ntohs(data->client_addr.sin_port);
    int Sock_fd = data->client_socket;

    printf("连接者的 IP: %s, 端口: %d\n", ip, port);

    char buf[1024];
    int login_flag = 0;
    char login_name[128];
    int ID = -1;

    while (1)
    {
        memset(buf, 0, sizeof(buf));
        ssize_t bytes_received = recv(Sock_fd, buf, sizeof(buf) - 1, 0);
        if (bytes_received < 0)
        {
            ERRLOG("接收错误");
            break;
        }
        else if (bytes_received == 0)
        {
            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
            update_state_by_id(db, ID, "off");
            close_db(db);
            pthread_mutex_unlock(&mutex);
            printf("用户 ID:%d   连接关闭\n", ID);
            login_flag = 0;
            break;
        }
        buf[bytes_received] = '\0'; // 确保字符串结束

        if (NULL != strstr(buf, "login"))
        {
            char str[1024];
            strcpy(str, buf);

            // 定义变量来存储分离出的部分
            char mode[256], username[256], password[256];
            str_set_mode(buf, mode, username, password);

            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }

            printf("id: %d", login_user_back_id(db, username, password));
            update_state_by_id(db, ID, "off");
            if (-1 != (ID = login_user_back_id(db, username, password)))
            {
                update_state_by_id(db, ID, "on");
                update_client_data_by_id(db, ID, ip, port, Sock_fd);
                sprintf(str, "[登陆成功]  【%s】 欢迎回来！", username);
                send(Sock_fd, str, strlen(str), 0);
                strcpy(login_name, username);
                login_flag = 1;
            }
            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if (NULL != strstr(buf, "enroll"))
        {
            char str[1024];
            strcpy(str, buf);

            // 定义变量来存储分离出的部分
            char mode[256], username[256], password[256];

            str_set_mode(buf, mode, username, password);
            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
            enroll_user(db, username, password);
            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if (NULL != strstr(buf, "set_password_"))
        {
            char str[1024];
            strcpy(str, buf);

            // 定义变量来存储分离出的部分
            char mode[256], mode2[256], password[256];

            str_set_mode(buf, mode, mode2, password);

            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
            update_password_by_id(db, ID, password);
            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if (NULL != strstr(buf, "set_name_"))
        {
            char str[1024];
            strcpy(str, buf);

            // 定义变量来存储分离出的部分
            char mode[256], mode2[256], name[256];

            str_set_mode(buf, mode, mode2, name);

            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
            if (SQLITE_OK == update_name_by_id(db, ID, name))
            {
                send(Sock_fd, "修改用户名成功", strlen("修改用户名成功"), 0);
            }
            else
            {
                strcpy(login_name, name);
                send(Sock_fd, "修改用户名成功", strlen("修改用户名成功"), 0);
            }

            close_db(db);
            pthread_mutex_unlock(&mutex);
        }

        else if (NULL != strstr(buf, "send_user_") && 1 == login_flag)
        {
            char username[256], buff[BUFFER_SIZE]; // 用于存储分割后的部分
            str_user_msg(buf, username, buff);

            printf("username: '%s'\n", username);
            printf("Buf: '%s'\n", buff);
            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
            int send_id = sql_get_id_by_username(db, username);
            char send_buff[2048];

            sprintf(send_buff, "[msg][user][%s]: %s", login_name, buff);

            int state = find_Friend(db, ID, send_id);
            int request_index = strcmp("agree", sql_get_request_by_id(db, ID, send_id));
            printf("send_id :%d ,state: %d \n", send_id, state);
            if (-1 != send_id && (0 == state) && !request_index)
                send_client_by_id(db, send_id, send_buff, Sock_fd);
            else if (-1 == state || 0 != request_index)
            {
                send(Sock_fd, "未找到该好友", strlen("未找到该好友"), 0);
            }
            else if (-2 == state)
            {
                send(Sock_fd, "好友离线", strlen("好友离线"), 0);
            }
            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if ((NULL != strstr(buf, "add_user_") && 1 == login_flag))
        {
            char str[1024];
            strcpy(str, buf);

            // 定义变量来存储分离出的部分
            char mode[256], mode1[256], Friendsname[256];
            str_set_mode(buf, mode, mode1, Friendsname);

            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }

            int Friends_ID = sql_get_id_by_username(db, Friendsname);
            printf("ID_find:%d\n", Friends_ID);
            if (-1 == Friends_ID)
            {
                send(Sock_fd, "该用户不存在", strlen("该用户不存在"), 0);
                pthread_mutex_unlock(&mutex);
                close_db(db);
                continue;
            }
            if (SQLITE_OK != post_Friends(db, login_name, ID, Friendsname, Friends_ID))
            {
                send(Sock_fd, "该用户已存在好友列表", strlen("该用户已存在好友列表"), 0);
                pthread_mutex_unlock(&mutex);
                close_db(db);
                continue;
            }
            else
            {
                send(Sock_fd, "好友申请发送成功", strlen("好友申请发送成功"), 0);
            }

            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if ((NULL != strstr(buf, "delete_friend_") && 1 == login_flag))
        {
            char str[1024];
            strcpy(str, buf);
            // 定义变量来存储分离出的部分
            char mode[256], mode1[256], Friendsname[256];
            str_set_mode(buf, mode, mode1, Friendsname);

            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }

            int Friends_ID = sql_get_id_by_username(db, Friendsname);
            printf("ID_find:%d\n", Friends_ID);
            if (-1 == Friends_ID)
            {
                send(Sock_fd, "该用户不存在", strlen("该用户不存在"), 0);
                pthread_mutex_unlock(&mutex);
                close_db(db);
                continue;
            }
            if (SQLITE_OK != post_Friends(db, login_name, ID, Friendsname, Friends_ID))
            {
                delete_Friend(db, ID, Friends_ID);
                delete_Friend(db, Friends_ID, ID);
                send(Sock_fd, "删除成功", strlen("删除成功"), 0);
                pthread_mutex_unlock(&mutex);
                close_db(db);
                continue;
            }

            close_db(db);
            pthread_mutex_unlock(&mutex);
        }

        else if ((NULL != strstr(buf, "get_friends_") && 1 == login_flag))
        {
            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
            findFriendIDsByNameID(db, ID, Sock_fd);
            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if ((NULL != strstr(buf, "agree_friends_") && 1 == login_flag))
        {
            char str[1024];
            strcpy(str, buf);
            // 定义变量来存储分离出的部分
            char mode[256], mode1[256], friends_name[256];
            str_set_mode(buf, mode, mode1, friends_name);
            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
            int Friends_ID = sql_get_id_by_username(db, friends_name);
            if (0 == agree_Friends(db, login_name, ID, friends_name, Friends_ID))
            {
                char send_buff[BUFFER_SIZE];
                memset(send_buff, 0, sizeof(send_buff));
                sprintf(send_buff, "  成功同意 %s 好友申请\n", friends_name);
                send(Sock_fd, send_buff, strlen(send_buff), 0);
            }
            else
            {
                send(Sock_fd, "好友申请不存在", strlen("申请不存在"), 0);
            }

            close_db(db);
            pthread_mutex_unlock(&mutex);
        }

        else if ((NULL != strstr(buf, "create_group_") && 1 == login_flag))
        {
            char str[1024];
            strcpy(str, buf);

            // 定义变量来存储分离出的部分
            char mode[256], mode1[256], group_name[256];
            str_set_mode(buf, mode, mode1, group_name);

            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
            if (0 == Create_group(db, ID, login_name, group_name))
            {
                send(Sock_fd, "创建成功\n", sizeof("创建成功\n"), 0);
            }
            else
            {
                send(Sock_fd, "创建失败\n", sizeof("创建失败\n"), 0);
            }

            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if ((NULL != strstr(buf, "add_group_") && 1 == login_flag))
        {
            char str[1024];
            strcpy(str, buf);

            // 定义变量来存储分离出的部分
            char mode[256], mode1[256], group_name[256];
            str_set_mode(buf, mode, mode1, group_name);

            pthread_mutex_lock(&mutex);

            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }

            if (1 == find_group(db, group_name))
            {
                add_group(db, ID, login_name, group_name);
                char buffer[BUFFER_SIZE];
                memset(buffer, 0, sizeof(buffer));
                sprintf(buffer, "成功加入群组 : %s ", group_name);
                send(Sock_fd, buffer, sizeof(buffer), 0);
            }
            else
            {
                char buffer[BUFFER_SIZE];
                memset(buffer, 0, sizeof(buffer));
                sprintf(buffer, "未找到群组 : %s ", group_name);
                send(Sock_fd, buffer, sizeof(buffer), 0);
            }
            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if ((NULL != strstr(buf, "exit_group_") && 1 == login_flag))
        {
            char str[1024];
            strcpy(str, buf);
            // 定义变量来存储分离出的部分
            char mode[256], mode1[256], group_name[256];
            str_set_mode(buf, mode, mode1, group_name);

            pthread_mutex_lock(&mutex);

            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }

            if (1 == find_group(db, group_name))
            {
                delete_Group(db, ID, group_name);
                char buffer[BUFFER_SIZE];
                memset(buffer, 0, sizeof(buffer));
                sprintf(buffer, "成功退出群组 : %s ", group_name);
                send(Sock_fd, buffer, sizeof(buffer), 0);
            }
            else
            {
                char buffer[BUFFER_SIZE];
                memset(buffer, 0, sizeof(buffer));
                sprintf(buffer, "未找到群组 : %s ", group_name);
                send(Sock_fd, buffer, sizeof(buffer), 0);
            }
            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if ((NULL != strstr(buf, "send_group_") && 1 == login_flag))
        {
            char groupname[256], buff[BUFFER_SIZE]; // 用于存储分割后的部分
            str_user_msg(buf, groupname, buff);

            printf("groupname: '%s'\n", groupname);
            printf("Buf: '%s'\n", buff);
            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }

            /**/
            if (1 == find_ID_by_group(db, groupname, ID))
                sql_get_group_by_groupname(db, groupname, Sock_fd, buff);
            else
                send(Sock_fd, "未加入该群组", strlen("未加入该群组"), 0);

            // sql_print_msgs_by_id(db,ID,login_name);

            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if ((NULL != strstr(buf, "get_groupname_") && 1 == login_flag))
        {

            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
            findgroup_name_ByNameID(db, ID, Sock_fd);
            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if ((NULL != strstr(buf, "get_groupuser_") && 1 == login_flag))
        {
      
            char mode[256], mode1[256], group_name[256];
            str_set_mode(buf, mode, mode1, group_name);

            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
    
            send_username_by_groupname(db,group_name,Sock_fd);
            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if ((NULL != strstr(buf, "send_circle_") && 1 == login_flag)) // 发送朋友圈
        {
            char groupname[256], buff[BUFFER_SIZE]; // 用于存储分割后的部分
            str_user_msg(buf, groupname, buff);

            // printf("groupname: '%s'\n", groupname);
            printf("Buf: '%s'\n", buff);
            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
            insert_Circle(db, login_name, ID, buff);
            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if ((NULL != strstr(buf, "get_circle_") && 1 == login_flag)) // 发送朋友圈
        {
            char groupname[256], buff[BUFFER_SIZE]; // 用于存储分割后的部分
            str_user_msg(buf, groupname, buff);

            // printf("groupname: '%s'\n", groupname);
            printf("Buf: '%s'\n", buff);
            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }
            send_msg_by_Friends(db, ID, Sock_fd);

            close_db(db);
            pthread_mutex_unlock(&mutex);
        }
        else if ((NULL != strstr(buf, "delete_circle_") && 1 == login_flag)) // 发送朋友圈
        {
            char groupname[256], buff[BUFFER_SIZE]; // 用于存储分割后的部分
            str_user_msg(buf, groupname, buff);

            // printf("groupname: '%s'\n", groupname);
            printf("Buf: '%s'\n", buff);
            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }

            if (-1 == select_circle_msg(db, ID, atoi(buff)))
            {
                send(Sock_fd, "未找到该消息\n", sizeof("未找到该消息\n"), 0);
            }
            else
            {
                delete_circle_msg(db, ID, atoi(buff));
                send(Sock_fd, "删除成功\n", sizeof("删除成功\n"), 0);
            }

            close_db(db);
            pthread_mutex_unlock(&mutex);
        }

        else if ((NULL != strstr(buf, "send_file")) && (1 == login_flag))
        {
            char mode[256], mode1[256], client_name[256];
            str_set_mode(buf, mode, mode1, client_name);

            pthread_mutex_lock(&mutex);
            const char *db_name = "data/cloud_chat.db";
            sqlite3 *db = init_db(db_name);
            if (!db)
            {
                return NULL;
            }

            int send_ID = sql_get_id_by_username(db, client_name);
            int send_sock_fd;

            if (-1 == (send_sock_fd = sql_get_sock_fd_by_id(db, send_ID)) || (!strcmp("off", sql_get_state_by_id(db, send_ID))))
            {
                send(Sock_fd, "目标用户不可到达", sizeof("目标用户不可到达"), 0);
                close_db(db);
                pthread_mutex_unlock(&mutex);
                continue;
            }
            close_db(db);
            pthread_mutex_unlock(&mutex);
            send(Sock_fd, "file server Ready_OK", sizeof("file server Ready_OK"), 0);
            printf("send_sock_fd : %d\n", send_sock_fd);
            send(Sock_fd, "send file name", sizeof("send file name"), 0);
            recv(Sock_fd, buf, sizeof(buf), 0);
            send(send_sock_fd, "recv file_name", sizeof("recv file name"), 0);
            send(send_sock_fd, buf, sizeof(buf), 0);
            send(Sock_fd, "Ready_\n send File Data", sizeof("Ready_\n send File Data"), 0);
            send(send_sock_fd, "Ready_\n recv File Data", sizeof("Ready_\n recv File Data"), 0);

            while ((bytes_received = recv(Sock_fd, buf, sizeof(buf), 0)) > 0)
            {
                if (NULL != strstr(buf, "file_end"))
                {
                    send(Sock_fd, "发送结束", sizeof("发送结束"), 0);
                    break;
                }
                if (write(send_sock_fd, buf, bytes_received) == -1)
                {
                    perror("写入文件错误");
                    break;
                }
            }

            printf("文件接收完毕\n");
        }
        else if ((NULL != strstr(buf, "help_")) && (1 == login_flag))
        {
            pthread_mutex_lock(&mutex);
            int fd = open("README", O_RDONLY);
            if (-1 == fd)
            {
                perror("文件打开失败");
                break;
            }

            char buf[BUFFER_SIZE];
            memset(buf, 0, sizeof(buf));
            int bytes;
            while (0 < (bytes = read(fd, buf, sizeof(buf))))
            {

                write(Sock_fd, buf, bytes);
                printf("%.*s", bytes, buf);
                memset(buf, 0, sizeof(buf));
            }
            close(fd);
            pthread_mutex_unlock(&mutex);
        }

        printf("接收到: %s\n", buf);
    }

    close(Sock_fd); // 关闭套接字
    return NULL;
}
